/***********************************************************************************
*	File: WinMain.cpp
*	Author: Keisuke Miyazaki
*	Project: Straw Man
*	Date: 09/13/2013
*	
*	Standard WinMain
*	Partially used "WinMain.cpp" by Doug Monroe, David Brown, & Jensen Rivera 
*	for Student Game Projects
*	Modified for String Tables and Modal Dialogue.
/***********************************************************************************/

#include <windows.h>
#include <tchar.h>
#include <vld.h>	

#include "Game.h"

const TCHAR*	szWINDOW_TITLE				= _T("Straw Man");
const TCHAR*	szWINDOW_CLASS				= _T("Straw Man");
const int		nWINDOW_DEFAULT_WIDTH		= 800;					
const int		nWINDOW_DEFAULT_HEIGHT		= 600;					
const BOOL		bIS_WINDOWED				= TRUE;

BOOL IsAlreadyRunning( void );
BOOL RegisterWindowClass( HINSTANCE hInstance );
HWND MakeWindow( HINSTANCE hInstance );
LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
INT_PTR CALLBACK About( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;
	HWND hWnd;
/*	HACCEL hAccelTable;*/

	if( hPrevInstance == 0 )
	{
		if( IsAlreadyRunning() == TRUE )
			return -1;
	}

	if( RegisterWindowClass( hInstance ) == FALSE )
		return -2;

	hWnd = MakeWindow(hInstance);

	if( hWnd == 0 )
	{
		UnregisterClass( szWINDOW_CLASS, hInstance );
		return -3;
	}

	ShowWindow( hWnd, nCmdShow );
	UpdateWindow( hWnd );


	CGame* pGame = CGame::GetInstance();

	pGame->Initialize( hWnd, hInstance, nWINDOW_DEFAULT_WIDTH, nWINDOW_DEFAULT_HEIGHT, bIS_WINDOWED );

	while( true )
	{
		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) == TRUE )
		{ 
			if( msg.message == WM_QUIT )
				break;

			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			if( pGame->Status() == false )
				PostQuitMessage( 0 );
		}
	}

	pGame->Terminate();
	CGame::DeleteInstance();
	pGame = nullptr;

	UnregisterClass( szWINDOW_CLASS, hInstance );

	return (int)(msg.wParam);
}

BOOL IsAlreadyRunning( void )
{
	HWND hOtherWnd = FindWindow( szWINDOW_CLASS, szWINDOW_TITLE);

	if( hOtherWnd )
	{
		if( IsIconic( hOtherWnd ) == TRUE )
				ShowWindow( hOtherWnd, SW_RESTORE );

		SetForegroundWindow( hOtherWnd );

		return TRUE;
	}

	return FALSE;
}

BOOL RegisterWindowClass( HINSTANCE hInstance )
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WindowProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, IDI_APPLICATION/*MAKEINTRESOURCE(Replace me Later)*/);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
	wcex.lpszMenuName	= NULL/*MAKEINTRESOURCE(IDR_MENU1)*/;
	wcex.lpszClassName	= szWINDOW_CLASS;
	wcex.hIconSm		= NULL/*(LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL))*/;

	return RegisterClassEx(&wcex);
}

HWND MakeWindow( HINSTANCE hInstance )
{
	DWORD dwWindowStyleFlags = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;

	RECT rWindow;
	rWindow.left	= 0;
	rWindow.top		= 0;
	rWindow.right	= nWINDOW_DEFAULT_WIDTH;
	rWindow.bottom	= nWINDOW_DEFAULT_HEIGHT;

	AdjustWindowRectEx( &rWindow, 
						dwWindowStyleFlags,
						FALSE, 
						WS_EX_APPWINDOW );
	
	int nWindowWidth	= rWindow.right - rWindow.left;
	int nWindowHeight	= rWindow.bottom - rWindow.top;

	return CreateWindowEx
		(
			WS_EX_APPWINDOW,														//	Extended Style flags.
			szWINDOW_CLASS,															//	Window Class Name.
			szWINDOW_TITLE,															//	Title of the Window.
			dwWindowStyleFlags,														//	Window Style Flags.
			(int)((GetSystemMetrics(SM_CXSCREEN) - nWindowWidth) * 0.5f),			//	Window Start Point (x, y). 
			(int)((GetSystemMetrics(SM_CYSCREEN) - nWindowHeight) * 0.5f),			//	Center the window over the desktop.
			nWindowWidth,															//	Width of Window.
			nWindowHeight,															//	Height of Window.
			HWND_DESKTOP,															//	Handle to parent window.
			NULL,																	//	Handle to menu.
			hInstance,																//	Application Instance.
			NULL)
		;	
}

LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
	case WM_CREATE: 
	case WM_SYSKEYUP:
	case WM_SYSCHAR:
	case WM_ACTIVATE:
		break;
	case WM_DESTROY: 
		{		
			PostQuitMessage( 0 );
		}
		break;

	case WM_CLOSE:
		{
			DestroyWindow(hWnd);			
		}
		break;

	case WM_PAINT:
		{
			PAINTSTRUCT	ps;
			HDC			hdc;

			hdc = BeginPaint( hWnd,&ps );
			EndPaint( hWnd,&ps );
		}
		break;

	default:
		return DefWindowProc( hWnd, msg, wParam, lParam );
	}
	return 0;
}

INT_PTR CALLBACK About( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	UNREFERENCED_PARAMETER(lParam);
	switch (msg)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hWnd, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
